package edu.pku.sei.modeler.editparts;

import static java.lang.Math.max;

import java.util.Iterator;

import edu.pku.sei.modeler.model.uml.BasicInteractions.Message;
import edu.pku.sei.modeler.model.uml.BasicInteractions.MessageSort;
import edu.pku.sei.modeler.model.uml.Kernel.OpaqueExpression;
import edu.pku.sei.modeler.model.uml.Kernel.ValueSpecification;
/**
 * /**
 * Assists parsing and formatting of Message labels. Syntax for the Message name is the
 * following:
 * 
 * <pre>
 *   messageident ::= [attribute =] signal-or-operation-name 
 *                    [ ( arguments) ][: return-value] | ??
 *   arguments ::= argument [ , arguments]
 *   argument ::= [parameter-name=]argument-value 
 *            | attribute= out-parameter-name [:argument-value]
 *            | -
 * </pre>
 * 
 * <p>
 * The current parsing algorithm is very crude. It is intended only as a placeholder until
 * a proper and complete algorithm is developed.
 * </p>
 * @author zsj
 *
 */
public class MessageParser {
	public static class Result {
		public String signalOrOperationName;

		public String[] argumentValue;
	}

	public static Result parse(final String label) {
		final Result result = new Result();

		// Find signal or operation name
		int start = max(label.indexOf('=') + 1, 0);
		int end = label.indexOf('(', start);
		if (end < 0) {
			end = label.indexOf(':', start);
			if (end < 0)
				end = label.length();
		}

		if (start < label.length())
			result.signalOrOperationName = label.substring(start, end).trim();
		else
			result.signalOrOperationName = label;

		// Find arguments
		start = label.indexOf('(');
		end = label.lastIndexOf(')');
		if (start >= 0 && end >= 0 && start < end) {
			result.argumentValue = new String[1];
			result.argumentValue[0] = label.substring(start + 1, end);
		} else
			result.argumentValue = new String[0];

		return result;
	}

	public static String format(final Message message) {
		return internalFormat(message, false);
	}

	public static String formatForEdit(final Message message) {
		return internalFormat(message, true);
	}

	@SuppressWarnings("unchecked")
	private static String internalFormat(final Message message,
			final boolean forEdit) {
		final StringBuilder buf = new StringBuilder();

//		final boolean hasKeywords = !message.getKeywords().isEmpty();
//		final boolean isCreateOrDestroy = (message.getMessageSort() == MessageSort.CREATE_MESSAGE_LITERAL || message
//				.getMessageSort() == MessageSort.DELETE_MESSAGE_LITERAL);
		final boolean hasKeywords = false;
		final boolean isCreateOrDestroy = false;
		

		if (!forEdit
				&& (hasKeywords || isCreateOrDestroy || message
						.getMessageSort() == MessageSort.asynchSignal)) {
			buf.append(String.valueOf("\u00AB"));
			if (hasKeywords) {
//				Set<String> keywords = (Set<String>) message.getKeywords();
//				for (String keyword : keywords) {
//					if (buf.length() > 1)
//						buf.append(",");
//					buf.append(keyword);
//				}
			}
			if (isCreateOrDestroy) {
//				if (message.getMessageSort() == MessageSort.CREATE_MESSAGE_LITERAL) {
//					if (buf.length() > 1)
//						buf.append(",");
//					buf.append("create");
//				}
//				if (message.getMessageSort() == MessageSort.DELETE_MESSAGE_LITERAL) {
//					if (buf.length() > 1)
//						buf.append(",");
//					buf.append("delete");
//				}
			}
			if (message.getMessageSort() == MessageSort.asynchSignal) {
				if (buf.length() > 1) {
					buf.append(",");
				}
				buf.append("signal");
			}
			buf.append(String.valueOf("\u00BB"));
			buf.append(" ");
		}

		buf.append(message.getName());

		if (!message.getArgument().isEmpty()) {
			buf.append("(");

			//boolean separator = false;
			for (Iterator iter = message.getArgument().iterator(); iter.hasNext();) {
				ValueSpecification element = (ValueSpecification) iter.next();
				if (element instanceof OpaqueExpression) {
					OpaqueExpression expr = (OpaqueExpression) element;
					//List<String> bodies = expr.getbody();
					
//					if (! expr.getbody().isEmpty()) {
//						if (separator)
//							buf.append(", ");
//						else
//							separator = true;
						buf.append(expr.getBody());
	//				}
				}
			}
		

			buf.append(")");
		}
		return buf.toString();
	}
}
